# -*- coding: utf-8 -*-

'''
projecto- classe que permite testar e comparar o desempenho de
um algoritmo de ordenação com um elemento de entrada
autor- Ana Isabel Marques 6052
data de criação do módulo- 27/05/2013
'''

from insertion_sort import *
from bubble_sort import *
from heapsort import *
from merge_sort import *
from quicksort import *

from random import uniform
import time
import math
from lista import *
from calculos import *

class EstatisticasAlgoritmo:

	'''
        Construtor
        @param A - lista
        @param numero de execuções - numero de execuções
        @tipoOrd - tipo de ordenação (algoritmo de ordenação escolhido pelo utilizador)
        '''
	def __init__(self, A, numeroExecucoes, tipoOrd):
                
                self.A = A
                self.numeroExecucoes = numeroExecucoes
                self.tipoOrd = tipoOrd
                self.TEMPOS = []

                pass

        '''
        Calcula as medidas estatísticas: média, variância, desvio-padrão
        Retorna uma string 
	@param numeroExecuções - número de execuções em que o algoritmo é
	executado para efeito de estatísticas
	'''
        def calcularEstatisticas(self):

                tempoTotal = 0
                string = ""
                for k in range(1, self.numeroExecucoes + 1):
                        
                        t1 = time.time()
                        self.tipoOrdenacao()
                        t2 = time.time()
        
                        tempoTotal = t2-t1
        
                        string += "Número de execução: {0}  - Tempo Total de Execução : {1}\n" .format(k, tempoTotal) 
                        self.TEMPOS.append(tempoTotal)
                        pass
                
                calculo = Calculos()
                media = calculo.calculaMedia(self.TEMPOS)
                var = calculo.calculaVariancia(self.TEMPOS, media)
                desvioPadrao = calculo.calculaDesvioPadrao(var)                      
                erroAmostral = calculo.calculaErroAmostral(var, len(self.A))

                string += "Estatísticas: \nMédia: {0}\nVariância: {1}\nDesvio Padrão: {2}\nErro Amostral: {3}\n" .format(media, var, desvioPadrao, erroAmostral)
                return string
                pass

        
        '''
        Conforme o algoritmo de ordenação escolhido pelo utilizador,
        a lista é ordenada com o algoritmo escolhido. 
        '''
        def tipoOrdenacao(self):
                lista = list(self.A)
                if(self.tipoOrd == 0):
                        algoritmo = InsertionSort(lista)
                        algoritmo.insertion_sort()
                        pass
                elif(self.tipoOrd == 1):
                        algoritmo = BubbleSort(lista)
                        algoritmo.bubble_sort()
                        pass
                elif(self.tipoOrd == 2):
                        algoritmo = Heapsort(lista)
                        algoritmo.heapsort()
                        pass
                elif(self.tipoOrd == 3):
                        algoritmo = MergeSort(lista)
                        algoritmo.merge_sort(0, len(lista)-1)
                        pass
                else:
                        algoritmo = Quicksort(lista)
                        algoritmo.quicksort(0, len(lista)-1)
                        pass
                pass
        pass
pass

